#include "VSMorphBaseFunction.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
using namespace VSEngine2;
IMPLEMENT_RTTI_NoCreateFun(VSMorphBaseFunction,VSController)
VSMorphBaseFunction::VSMorphBaseFunction()
{
	m_pInput.Clear();
	m_pOutput.Clear();
	m_pOwner = NULL;
	m_bIsVisited = 0;
}
VSMorphBaseFunction::VSMorphBaseFunction(const VSUsedName & ShowName,VSMorphTree * pMorphTree)
{
	m_ShowName = ShowName;
	m_pInput.Clear();
	m_pOutput.Clear();
	VSMAC_ASSERT(pMorphTree);
	m_pOwner = pMorphTree;
	m_pOwner->AddMorphFunction(this);
	m_bIsVisited = 0;

}
VSMorphBaseFunction::~VSMorphBaseFunction()
{
	for(unsigned int i = 0 ; i < m_pInput.GetNum() ; i++)
	{
		VSMAC_DELETE(m_pInput[i]);
	}
	for(unsigned int i = 0 ; i < m_pOutput.GetNum() ; i++)
	{
		VSMAC_DELETE(m_pOutput[i]);
	}
	m_pOwner->DeleteMorphFunction(this);
}
bool VSMorphBaseFunction::Register(VSStream & rStream)const
{
	if (rStream.IsObjectRegister(this))
	{
		return 1;
	}
	if(!VSController::Register(rStream))
		return 0;

	for(unsigned int i = 0 ; i < m_pInput.GetNum() ; i++)
	{
		if(!m_pInput[i]->Register(rStream))
			return 0;
	}

	for(unsigned int i = 0 ; i < m_pOutput.GetNum() ;i++)
	{
		if(!m_pOutput[i]->Register(rStream))
			return 0;
	}
	if(m_pOwner)
		if(!m_pOwner->Register(rStream))
			return 0;
	return 1;
}
unsigned int VSMorphBaseFunction::DiskUse()const
{
	unsigned int Used = VSController::DiskUse();

	Used += m_ShowName.DiskUse();
	Used += sizeof(VSInputNode *) * m_pInput.GetNum();
	Used += sizeof(VSOutputNode *) * m_pOutput.GetNum();
	Used +=sizeof(VSMorphTree *);
	Used += sizeof(unsigned int) * 2;
	return Used;
}
bool VSMorphBaseFunction::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	if(!VSController::Save(rStream,iSaveUse))
		return 0;

	
	m_ShowName.Save(rStream,iSaveUse);

	unsigned int uiInputNum = m_pInput.GetNum();
	if(!rStream.Write(&uiInputNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	unsigned int uiOutputNum = m_pOutput.GetNum();
	if(!rStream.Write(&uiOutputNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	for(unsigned int i = 0 ; i < uiInputNum ; i++)
	{
// 		VSInputNode * pInputNode = m_pInput[i];
// 		if(!rStream.Write(&pInputNode,sizeof(VSInputNode *)))
// 			return 0;
		if(!rStream.WriteObjectPtr(m_pInput[i]))
			return 0;
		iSaveUse += sizeof(VSInputNode *);
	}

	for(unsigned int i = 0 ; i < uiInputNum ; i++)
	{
// 		VSOutputNode * pOutputNode = m_pOutput[i];
// 		if(!rStream.Write(&pOutputNode,sizeof(VSOutputNode *)))
// 			return 0;
		if(!rStream.WriteObjectPtr(m_pOutput[i]))
			return 0;
		iSaveUse += sizeof(VSOutputNode *);
	}

// 	VSMorphTree * pMorphTree = m_pOwner;
// 	if(!rStream.Write(&pMorphTree,sizeof(VSMorphTree *)))
// 		return 0;
	if(!rStream.WriteObjectPtr(m_pOwner))
		return 0;
	iSaveUse += sizeof(VSMorphTree *);
	return 1;
}
bool VSMorphBaseFunction::Load(VSStream & rStream,unsigned int &iSaveUse)
{	
	if(!VSController::Load(rStream,iSaveUse))
		return 0;

	m_ShowName.Load(rStream,iSaveUse);

	unsigned int uiInputNum;
	if(!rStream.Read(&uiInputNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	unsigned int uiOutputNum;
	if(!rStream.Read(&uiOutputNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	m_pInput.SetBufferNum(uiInputNum);
	for(unsigned int i = 0 ; i < uiInputNum ; i++)
	{
// 		VSInputNode * pPutNode = NULL;
// 		if(!rStream.Read(&pPutNode,sizeof(VSInputNode *)))
// 			return 0;
// 		AddLink(pPutNode);
		if(!rStream.ReadObjectPtr(m_pInput[i]))
			return 0;
		iSaveUse += sizeof(VSInputNode *);
	}

	m_pOutput.SetBufferNum(uiOutputNum);
	for(unsigned int i = 0 ; i < uiOutputNum ; i++)
	{
// 		VSOutputNode * pPutNode = NULL;
// 		if(!rStream.Read(&pPutNode,sizeof(VSOutputNode *)))
// 			return 0;
// 		AddLink(pPutNode);

		if(!rStream.ReadObjectPtr(m_pOutput[i]))
			return 0;
		iSaveUse += sizeof(VSOutputNode *);
	}

// 	VSMorphTree * pMorphTree = NULL;
// 	if(!rStream.Read(&pMorphTree,sizeof(VSMorphTree *)))
// 		return 0;
// 	AddLink(pMorphTree);
	if(!rStream.ReadObjectPtr(m_pOwner))
		return 0;
	iSaveUse += sizeof(VSMorphTree *);

	return 1;
}
bool VSMorphBaseFunction::Link(VSStream & rStream)
{
	if(!VSController::Link(rStream))
		return 0;

	for(unsigned int i = 0 ; i < m_pInput.GetNum() ; i++)
	{
		//m_pInput[i] = (VSInputNode *)rStream.GetMapValue(GetNextLink());
		rStream.LinkObjectPtr(m_pInput[i]);
	}

	for(unsigned int i = 0 ; i < m_pOutput.GetNum() ;i++)
	{
		//m_pOutput[i] = (VSOutputNode *)rStream.GetMapValue(GetNextLink());
		rStream.LinkObjectPtr(m_pOutput[i]);
	}
	rStream.LinkObjectPtr(m_pOwner);
	//m_pOwner = (VSMorphTree *)rStream.GetMapValue(GetNextLink());
	return 1;

}
bool VSMorphBaseFunction::Clone(const VSObject *pObject,unsigned int uiType)
{
	const VSMorphBaseFunction* Temp = DynamicCast<VSMorphBaseFunction>(pObject); 
	if(!Temp)
		return 0;
	if(VSController::Clone(pObject,uiType))
	{

		m_ShowName = Temp->m_ShowName;
		m_pInput.Clear();
		m_pInput.SetBufferNum(Temp->m_pInput.GetNum());
		for (unsigned int i = 0 ; i < m_pInput.GetNum() ; i++)
		{
			VSInputNode * pTemp1  = Temp->m_pInput[i];
			VSInputNode * pTemp2 =(VSInputNode *)VSObject::GetInstance((pTemp1)->GetType().GetName());
			pTemp2->Clone(pTemp1,uiType);
			m_pInput[i] = pTemp2;	
			((VSPutNode *)pTemp2)->SetOwner(this);
		}

		m_pOutput.Clear();
		m_pOutput.SetBufferNum(Temp->m_pOutput.GetNum());
		for (unsigned int i = 0 ; i < m_pOutput.GetNum() ; i++)
		{
			VSOutputNode * pTemp1  = Temp->m_pOutput[i];
			VSOutputNode * pTemp2 =(VSOutputNode *)VSObject::GetInstance((pTemp1)->GetType().GetName());
			pTemp2->Clone(pTemp1,uiType);
			m_pOutput[i] = pTemp2;	
			((VSPutNode *)pTemp2)->SetOwner(this);
		}
		m_pOwner = Temp->m_pOwner;

		return 1;

	}
	else
	{
		return 0;
	}

}
bool VSMorphBaseFunction::UpdateEx(double dAppTime)
{
	if(!VSController::UpdateEx(dAppTime))
		return false;
	if(m_bIsVisited)
		return false;
	m_bIsVisited = 1;
	for (unsigned int i = 0 ; i < m_pInput.GetNum() ;i++)
	{
		if(m_pInput[i]->GetOutputLink())
		{
			VSMorphBaseFunction *pMorphBaseFunction = (VSMorphBaseFunction *)m_pInput[0]->GetOutputLink()->GetOwner();
			if(pMorphBaseFunction)
			{
				pMorphBaseFunction->Update(dAppTime);
			}
		}
	}
	return true;

}
VSInputNode * VSMorphBaseFunction::GetInputNode(unsigned int uiNodeID)const
{
	if(uiNodeID >=m_pInput.GetNum())
		return NULL;
	return m_pInput[uiNodeID];

}
VSInputNode * VSMorphBaseFunction::GetInputNode(const VSString & NodeName)const
{
	for (unsigned int i  =0 ; i < m_pInput.GetNum(); i++)
	{
		if(m_pInput[i]->GetNodeName() == NodeName)
			return m_pInput[i];
	}
	return NULL;
}

VSOutputNode * VSMorphBaseFunction::GetOutputNode(unsigned int uiNodeID)const
{
	if(uiNodeID >=m_pOutput.GetNum())
		return NULL;
	return m_pOutput[uiNodeID];
}
VSOutputNode * VSMorphBaseFunction::GetOutputNode(const VSString & NodeName)const
{
	for (unsigned int i  =0 ; i < m_pInput.GetNum(); i++)
	{
		if(m_pOutput[i]->GetNodeName() == NodeName)
			return m_pOutput[i];
	}
	return NULL;
}
void VSMorphBaseFunction::AddAllPutNodeTo(VSArray<VSPutNode *>& LinkArray)
{
	for (unsigned int i = 0 ; i < m_pInput.GetNum() ; i++)
	{

		LinkArray.AddElement(m_pInput[i]);	
	}

	for (unsigned int i = 0 ; i < m_pOutput.GetNum() ; i++)
	{

		LinkArray.AddElement(m_pOutput[i]);	
	}	
}
bool VSMorphBaseFunction::Link(const VSArray<VSPutNode *>& OldLink,const VSArray<VSPutNode *>& NewLink)
{
	for (unsigned int i = 0 ; i < m_pInput.GetNum() ; i++)
	{

		if(!m_pInput[i]->Link(OldLink,NewLink))
			return 0;
	}

	for (unsigned int i = 0 ; i < m_pOutput.GetNum() ; i++)
	{

		if(!m_pOutput[i]->Link(OldLink,NewLink))
			return 0;
	}	
	return 1;
}
void VSMorphBaseFunction::ClearFlag()
{
	m_bIsVisited = 0;
}